package com.inspur.icity.bus.base.core.web;

import com.inspur.icity.bus.base.core.exception.ApplicationException;
import com.inspur.icity.bus.base.core.exception.ForbiddenException;
import com.inspur.icity.bus.base.core.exception.UnAuthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import com.inspur.icity.bus.base.core.exception.Error;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *凡是方法标识@ResponseBody的遇到异常都返回为JSON格式
 */
public class DefaultExceptionHandler extends AbstractHandlerMethodExceptionResolver {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception ex) {

        if(!"java.io.IOException: Broken pipe".equals(ex.getMessage())) {
            logger.error(ex.getMessage(), ex);
        }

        int errorCode = 200;
        int responseCode = 200;
        if("org.apache.shiro.authz.UnauthorizedException".equals(ex.getClass().getName())){
            responseCode = HttpServletResponse.SC_FORBIDDEN;
            errorCode = responseCode;
        } else if(ex instanceof UnAuthorizedException){
            responseCode = HttpServletResponse.SC_UNAUTHORIZED;
            errorCode = responseCode;
        } else if (ex instanceof ForbiddenException){
            responseCode = HttpServletResponse.SC_FORBIDDEN;
            errorCode = responseCode;
        } else if(ex instanceof ApplicationException){
            responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
        } else if(ex instanceof Throwable){
            responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
            errorCode = responseCode;
        }

        response.setStatus(responseCode);

        //JSON
        if(handlerMethod.getMethodAnnotation(ResponseBody.class) != null){
                Error error = new Error();
                error.setCode(errorCode);
                error.setError(ex.getMessage());
                ModelAndView mav = new ModelAndView(new MappingJackson2JsonView());
                mav.addObject(error);
                return mav;
        }

        //VIEW
        ModelAndView mv = new ModelAndView();
        mv.addObject("error", ex);
        if(responseCode == HttpServletResponse.SC_FORBIDDEN){
            mv.setViewName("error/403");
        }else{
            mv.setViewName("error/500");
        }
        return mv;
    }

}
